﻿using System;
using System.Configuration;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Web.Security;

namespace Framework
{
    /// <summary>
    /// 加密/解密类。
    /// </summary>
    public class DataEncryption
    {
        static DataEncryption()
        {
            if (string.IsNullOrEmpty(EncryptionKey))
                EncryptionKey = "12345678";
            MobjCryptoService = new RijndaelManaged();
            Key = "Guz(%&hj7x89H$yuBI0456FtmaT5&fvHUFCy76*h%(HilJ$lhj!y6&(*jkP87jH7";
        }
        #region ========加密========
        private static readonly string EncryptionKey = ConfigurationManager.AppSettings["EncryptionKey"];
        public static string Key64 = "";
        public static string Iv64 = "";
        private static readonly byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string Encrypt(string text)
        {

            return Encrypt(text, EncryptionKey);
        }
        /// <summary> 
        /// 加密数据 
        /// </summary> 
        /// <param name="text"></param> 
        /// <param name="key"></param> 
        /// <returns></returns> 
        public static string Encrypt(string text, string key)
        {
            var des = new DESCryptoServiceProvider();
            byte[] inputByteArray = Encoding.Default.GetBytes(text);
            var hashPasswordForStoringInConfigFile = FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5");
            if (hashPasswordForStoringInConfigFile != null)
                des.Key = Encoding.ASCII.GetBytes(hashPasswordForStoringInConfigFile.Substring(0, 8));
            var passwordForStoringInConfigFile = FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5");
            if (passwordForStoringInConfigFile != null)
                des.IV = Encoding.ASCII.GetBytes(passwordForStoringInConfigFile.Substring(0, 8));
            var ms = new MemoryStream();
            var cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            var ret = new StringBuilder();
            foreach (var b in ms.ToArray())
            {
                ret.AppendFormat("{0:X2}", b);
            }
            return ret.ToString();
        }

        #endregion
        #region ========解密========
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string Decrypt(string text)
        {
            return Decrypt(text, EncryptionKey);
        }
        /// <summary> 
        /// 解密数据 
        /// </summary> 
        /// <param name="text"></param> 
        /// <param name="key"></param> 
        /// <returns></returns> 
        public static string Decrypt(string text, string key)
        {
            var des = new DESCryptoServiceProvider();
            int len = text.Length / 2;
            var inputByteArray = new byte[len];
            int x;
            for (x = 0; x < len; x++)
            {
                int i = Convert.ToInt32(text.Substring(x * 2, 2), 16);
                inputByteArray[x] = (byte)i;
            }
            var hashPasswordForStoringInConfigFile = FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5");
            if (hashPasswordForStoringInConfigFile != null)
                des.Key = Encoding.ASCII.GetBytes(hashPasswordForStoringInConfigFile.Substring(0, 8));
            var passwordForStoringInConfigFile = FormsAuthentication.HashPasswordForStoringInConfigFile(key, "md5");
            if (passwordForStoringInConfigFile != null)
                des.IV = Encoding.ASCII.GetBytes(passwordForStoringInConfigFile.Substring(0, 8));
            var ms = new MemoryStream();
            var cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            return Encoding.Default.GetString(ms.ToArray());
        }

        #endregion

     
        /// <summary>
        /// SHA1加密字符串
        /// </summary>
        /// <param name="source">源字符串</param>
        /// <returns>加密后的字符串</returns>
        public string Sha1(string source)
        {
            return FormsAuthentication.HashPasswordForStoringInConfigFile(source, "SHA1");
        }


        /// <summary>
        /// MD5加密字符串
        /// </summary>
        /// <param name="source">源字符串</param>
        /// <returns>加密后的字符串</returns>
        public string Md5(string source)
        {
            return FormsAuthentication.HashPasswordForStoringInConfigFile(source, "MD5");
        }

        public string Encode(string data)
        {
            byte[] byKey = Encoding.ASCII.GetBytes(Key64);
            byte[] byIv = Encoding.ASCII.GetBytes(Iv64);

            var cryptoProvider = new DESCryptoServiceProvider();
            var ms = new MemoryStream();
            var cst = new CryptoStream(ms, cryptoProvider.CreateEncryptor(byKey, byIv), CryptoStreamMode.Write);

            var sw = new StreamWriter(cst);
            sw.Write(data);
            sw.Flush();
            cst.FlushFinalBlock();
            sw.Flush();
            return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);

        }

        public string Decode(string data)
        {
            byte[] byKey = Encoding.ASCII.GetBytes(Key64);
            byte[] byIv = Encoding.ASCII.GetBytes(Iv64);

            byte[] byEnc;
            try
            {
                byEnc = Convert.FromBase64String(data);
            }
            catch
            {
                return null;
            }
            var cryptoProvider = new DESCryptoServiceProvider();
            var ms = new MemoryStream(byEnc);
            var cst = new CryptoStream(ms, cryptoProvider.CreateDecryptor(byKey, byIv), CryptoStreamMode.Read);
            var sr = new StreamReader(cst);
            return sr.ReadToEnd();
        }
        public string GetMd532(string s, string inputCharset)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] t = md5.ComputeHash(Encoding.GetEncoding(inputCharset).GetBytes(s));
            var sb = new StringBuilder(32);
            for (int i = 0; i < t.Length; i++)
            {
                sb.Append(t[i].ToString("x").PadLeft(2, '0'));
            }
            return sb.ToString();
        }

        //16位加密
        public static string GetMd516(string convertString)
        {
            var md5 = new MD5CryptoServiceProvider();
            string t2 = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(convertString)), 4, 8);
            t2 = t2.Replace("-", "");
            return t2;
        }

        private static readonly SymmetricAlgorithm MobjCryptoService;
        private static readonly string Key;

        /// <summary>   
        /// 获得密钥   
        /// </summary>   
        /// <returns>密钥</returns>   
        private static byte[] GetLegalKey()
        {
            string sTemp = Key;
            MobjCryptoService.GenerateKey();
            byte[] bytTemp = MobjCryptoService.Key;
            int keyLength = bytTemp.Length;
            if (sTemp.Length > keyLength)
                sTemp = sTemp.Substring(0, keyLength);
            else if (sTemp.Length < keyLength)
                sTemp = sTemp.PadRight(keyLength, ' ');
            return Encoding.ASCII.GetBytes(sTemp);
        }
        /// <summary>   
        /// 获得初始向量IV   
        /// </summary>   
        /// <returns>初试向量IV</returns>   
        private static byte[] GetLegalIv()
        {
            string sTemp = "E4ghj*Ghg7!rNIfb&95GUY86GfghUb#er57HBh(u%g6HJ($jhWk7&!hg4ui%$hjk";
            MobjCryptoService.GenerateIV();
            byte[] bytTemp = MobjCryptoService.IV;
            int ivLength = bytTemp.Length;
            if (sTemp.Length > ivLength)
                sTemp = sTemp.Substring(0, ivLength);
            else if (sTemp.Length < ivLength)
                sTemp = sTemp.PadRight(ivLength, ' ');
            return Encoding.ASCII.GetBytes(sTemp);
        }
        /// <summary>   
        /// 加密方法   
        /// </summary>   
        /// <param name="source">待加密的串</param>   
        /// <returns>经过加密的串</returns>   
        public static string Encrypto(string source)
        {
            byte[] bytIn = Encoding.UTF8.GetBytes(source);
            var ms = new MemoryStream();
            MobjCryptoService.Key = GetLegalKey();
            MobjCryptoService.IV = GetLegalIv();
            ICryptoTransform encrypto = MobjCryptoService.CreateEncryptor();
            var cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Write);
            cs.Write(bytIn, 0, bytIn.Length);
            cs.FlushFinalBlock();
            ms.Close();
            byte[] bytOut = ms.ToArray();
            return Convert.ToBase64String(bytOut);
        }
        /// <summary>   
        /// 解密方法   
        /// </summary>   
        /// <param name="source">待解密的串</param>   
        /// <returns>经过解密的串</returns>   
        public static string Decrypto(string source)
        {
            byte[] bytIn = Convert.FromBase64String(source);
            var ms = new MemoryStream(bytIn, 0, bytIn.Length);
            MobjCryptoService.Key = GetLegalKey();
            MobjCryptoService.IV = GetLegalIv();
            ICryptoTransform encrypto = MobjCryptoService.CreateDecryptor();
            var cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Read);
            var sr = new StreamReader(cs);
            return sr.ReadToEnd();
        }

   
        /// <summary>
        /// DES加密字符串
        /// </summary>
        /// <param name="encryptString">待加密的字符串</param>
        /// <param name="encryptKey">加密密钥,要求为8位</param>
        /// <returns>加密成功返回加密后的字符串，失败返回源串</returns>
        public static string EncryptDes(string encryptString, string encryptKey)
        {
            try
            {
                byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
                byte[] rgbIv = Keys;
                byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                var dCsp = new DESCryptoServiceProvider();
                var mStream = new MemoryStream();
                var cStream = new CryptoStream(mStream, dCsp.CreateEncryptor(rgbKey, rgbIv), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Convert.ToBase64String(mStream.ToArray());
            }
            catch
            {
                return encryptString;
            }
        }

        /// <summary>
        /// DES解密字符串
        /// </summary>
        /// <param name="decryptString">待解密的字符串</param>
        /// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>
        /// <returns>解密成功返回解密后的字符串，失败返源串</returns>
        public static string DecryptDes(string decryptString, string decryptKey)
        {
            try
            {
                byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey);
                byte[] rgbIv = Keys;
                byte[] inputByteArray = Convert.FromBase64String(decryptString);
                var dcsp = new DESCryptoServiceProvider();
                var mStream = new MemoryStream();
                var cStream = new CryptoStream(mStream, dcsp.CreateDecryptor(rgbKey, rgbIv), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Encoding.UTF8.GetString(mStream.ToArray());
            }
            catch
            {
                return decryptString;
            }
        }

        /// <summary>
        /// 加密文件
        /// </summary>
        /// <param name="inName"></param>
        /// <param name="outName"></param>
        /// <param name="desKey"></param>
        public static void EncryptFile(string inName, string outName, string desKey)
        {
            byte[] rgbKey = Encoding.UTF8.GetBytes(desKey);
            byte[] rgbIv = Keys;
            EncryptFile(inName, outName, rgbKey, rgbIv);
        }


        /// <summary>
        /// 加密文件
        /// </summary>
        /// <param name="inName"></param>
        /// <param name="outName"></param>
        /// <param name="desKey"></param>
        /// <param name="desIv"></param>
        private static void EncryptFile(String inName, String outName, byte[] desKey, byte[] desIv)
        {
            //Create the file streams to handle the input and output files.
            var fin = new FileStream(inName, FileMode.Open, FileAccess.Read);
            var fout = new FileStream(outName, FileMode.OpenOrCreate, FileAccess.Write);
            fout.SetLength(0);

            //Create variables to help with read and write.
            var bin = new byte[100]; //This is intermediate storage for the encryption.
            long rdlen = 0;              //This is the total number of bytes written.
            long totlen = fin.Length;    //This is the total length of the input file.
            DES des = new DESCryptoServiceProvider();
            var encStream = new CryptoStream(fout, des.CreateEncryptor(desKey, desIv), CryptoStreamMode.Write);
            //Read from the input file, then encrypt and write to the output file.
            while (rdlen < totlen)
            {
                int len = fin.Read(bin, 0, 100);                     //This is the number of bytes to be written at a time.
                encStream.Write(bin, 0, len);
                rdlen = rdlen + len;
            }

            encStream.Close();
            fout.Close();
            fin.Close();
        }

        /// <summary>
        /// 解密文件
        /// </summary>
        /// <param name="inName"></param>
        /// <param name="outName"></param>
        /// <param name="desKey"></param>
        public static void DecryptFile(string inName, string outName, string desKey)
        {
            byte[] rgbKey = Encoding.UTF8.GetBytes(desKey);
            byte[] rgbIv = Keys;
            DecryptFile(inName, outName, rgbKey, rgbIv);
        }
        /// <summary>
        /// 解密文件
        /// </summary>
        /// <param name="inName"></param>
        /// <param name="outName"></param>
        /// <param name="desKey"></param>
        /// <param name="desIv"></param>
        private static void DecryptFile(String inName, String outName, byte[] desKey, byte[] desIv)
        {
            //Create the file streams to handle the input and output files.
            var fin = new FileStream(inName, FileMode.Open, FileAccess.Read);
            var fout = new FileStream(outName, FileMode.OpenOrCreate, FileAccess.Write);
            fout.SetLength(0);
            //Create variables to help with read and write.
            var bin = new byte[100]; //This is intermediate storage for the encryption.
            long rdlen = 0;              //This is the total number of bytes written.
            long totlen = fin.Length;    //This is the total length of the input file.
            DES des = new DESCryptoServiceProvider();
            var encStream = new CryptoStream(fout, des.CreateDecryptor(desKey, desIv), CryptoStreamMode.Write);
            //Read from the input file, then encrypt and write to the output file.
            while (rdlen < totlen)
            {
                int len = fin.Read(bin, 0, 100);                     //This is the number of bytes to be written at a time.
                encStream.Write(bin, 0, len);
                rdlen = rdlen + len;
            }
            encStream.Close();
            fout.Close();
            fin.Close();
        }

        /// <summary>
        /// DES加密方法
        /// </summary>
        /// <param name="strPlain">明文</param>
        /// <param name="strDesKey">密钥</param>
        /// <param name="strDesiv">向量</param>
        /// <returns>密文</returns>
        public static string DesEncrypt(string strPlain, string strDesKey, string strDesiv)
        {
            //把密钥转换成字节数组
            byte[] bytesDesKey = Encoding.ASCII.GetBytes(strDesKey);
            //把向量转换成字节数组
            byte[] bytesDesiv = Encoding.ASCII.GetBytes(strDesiv);
            //声明1个新的DES对象
            var desEncrypt = new DESCryptoServiceProvider();
            //开辟一块内存流
            var msEncrypt = new MemoryStream();
            //把内存流对象包装成加密流对象
            var csEncrypt = new CryptoStream(msEncrypt, desEncrypt.CreateEncryptor(bytesDesKey, bytesDesiv), CryptoStreamMode.Write);
            //把加密流对象包装成写入流对象
            var swEncrypt = new StreamWriter(csEncrypt);
            //写入流对象写入明文
            swEncrypt.WriteLine(strPlain);
            //写入流关闭
            swEncrypt.Close();
            //加密流关闭
            csEncrypt.Close();
            //把内存流转换成字节数组，内存流现在已经是密文了
            byte[] bytesCipher = msEncrypt.ToArray();
            //内存流关闭
            msEncrypt.Close();
            //把密文字节数组转换为字符串，并返回
            return Encoding.Unicode.GetString(bytesCipher);
        }




        /// <summary>
        /// DES解密方法
        /// </summary>
        /// <param name="strCipher">密文</param>
        /// <param name="strDesKey">密钥</param>
        /// <param name="strDesiv">向量</param>
        /// <returns>明文</returns>
        public static string DesDecrypt(string strCipher, string strDesKey, string strDesiv)
        {
            //把密钥转换成字节数组
            byte[] bytesDesKey = Encoding.ASCII.GetBytes(strDesKey);
            //把向量转换成字节数组
            byte[] bytesDesiv = Encoding.ASCII.GetBytes(strDesiv);
            //把密文转换成字节数组
            byte[] bytesCipher = Encoding.Unicode.GetBytes(strCipher);
            //声明1个新的DES对象
            var desDecrypt = new DESCryptoServiceProvider();
            //开辟一块内存流，并存放密文字节数组
            var msDecrypt = new MemoryStream(bytesCipher);
            //把内存流对象包装成解密流对象
            var csDecrypt = new CryptoStream(msDecrypt, desDecrypt.CreateDecryptor(bytesDesKey, bytesDesiv), CryptoStreamMode.Read);
            //把解密流对象包装成读出流对象
            var srDecrypt = new StreamReader(csDecrypt);
            //明文=读出流的读出内容
            string strPlainText = srDecrypt.ReadLine();
            //读出流关闭
            srDecrypt.Close();
            //解密流关闭
            csDecrypt.Close();
            //内存流关闭
            msDecrypt.Close();
            //返回明文
            return strPlainText;
        }

        public static string SHA1Encrypt(string encryptText)
        {
            byte[] StrRes = Encoding.Default.GetBytes(encryptText);
            HashAlgorithm mySHA = new SHA1CryptoServiceProvider();
            StrRes = mySHA.ComputeHash(StrRes);
            var EnText = new StringBuilder();
            foreach (byte Byte in StrRes)
            {
                EnText.AppendFormat("{0:x2}", Byte);
            }
            return EnText.ToString();
        }
        public static string HMACSHA1Encrypt(string EncryptText, string EncryptKey)
        {
            byte[] StrRes = Encoding.Default.GetBytes(EncryptText);
            var myHMACSHA1 = new HMACSHA1(Encoding.Default.GetBytes(EncryptKey));
            var CStream = new CryptoStream(Stream.Null, myHMACSHA1, CryptoStreamMode.Write);
            CStream.Write(StrRes, 0, StrRes.Length);
            var EnText = new StringBuilder();
            foreach (byte Byte in StrRes)
            {
                EnText.AppendFormat("{0:x2}", Byte);
            }
            return EnText.ToString();
        }
        public static string MD5Encrypt(string CryptText)
        {
            MD5 myMD5 = new MD5CryptoServiceProvider();
            byte[] HashCode = Encoding.Default.GetBytes(CryptText);
            HashCode = myMD5.ComputeHash(HashCode);
            var EnText = new StringBuilder();
            foreach (byte Byte in HashCode)
            {
                EnText.AppendFormat("{0:x2}", Byte);
            }
            return EnText.ToString();
        }

        /// <summary>
        /// 字符串简单加密，通常用于URL加密
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public static string SimpleEncryp(string Value)
        {
            return Convert.ToBase64String(Encoding.Default.GetBytes(Value)).Replace("=", "%dh").Replace("&", "%yh");

        }

        /// <summary>
        /// 字符串简单解密，通常用于URL解密
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string SimpleDecrypt(string value)
        {
            return Encoding.Default.GetString(Convert.FromBase64String(value.Replace("%dh", "=").Replace("%yh", "&")));
        }
        public static string EncryptString(string value)
        {

            const string CIV = "kXwL7X2+fgM="; //密钥
            const string CKEY = "FwGQWRRgKCI="; //初始化向量
            SymmetricAlgorithm mCSP = new DESCryptoServiceProvider();
            ICryptoTransform ct = mCSP.CreateEncryptor(Convert.FromBase64String(CKEY), Convert.FromBase64String(CIV));
            byte[] byt = Encoding.UTF8.GetBytes(value);
            var ms = new MemoryStream();
            var cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
            cs.Write(byt, 0, byt.Length);
            cs.FlushFinalBlock();
            cs.Close();
            return Convert.ToBase64String(ms.ToArray());
        }

        public static string DecryptString(string Value)
        {
            const string CIV = "kXwL7X2+fgM="; //密钥
            const string CKEY = "FwGQWRRgKCI="; //初始化向量
            SymmetricAlgorithm mCSP = new DESCryptoServiceProvider();
            ICryptoTransform ct = mCSP.CreateDecryptor(Convert.FromBase64String(CKEY), Convert.FromBase64String(CIV));
            byte[] byt = Convert.FromBase64String(Value);
            var ms = new MemoryStream();
            var cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
            cs.Write(byt, 0, byt.Length);
            cs.FlushFinalBlock();
            cs.Close();
            return Encoding.UTF8.GetString(ms.ToArray());
        }
    }
}
